_package("alz.mui");

_import("alz.mui.Component");
_import("alz.mui.ListItem");

/**
 * 列表框
 */
_class("ListBox", Component, function(){
	this._init = function(){
		_super._init.call(this);
		this._model = null;
		this._filter = null;
		this._tableIndex = null;
		this._hash = {};
		this._list = [];
		this._activeItem = null;
		this._itemClass = null;
	};
	this.bind = function(obj, model, filter){
		if(model) this.setModel(model);
		if(filter) this.setFilter(filter);
		this.init(obj);
	};
	this.init = function(obj){
		_super.init.apply(this, arguments);
		this._self.onselectstart = function(){
			return false;
		};
		if(this._className == "ListBox"){
			var list = obj.getElementsByTagName("li");
			for(var i = 0, len = list.length; i < len; i++){
				//if(!list[i]._ptr){
				var item = new ListItem();
				item.bind(list[i], null, this);
				this.pushItem(item);
				if(item._self.className == "active"){
					this._activeItem = item;
				}
				item = null;
				//}
			}
			list = null;
		}
	};
	this.dispose = function(){
		this._itemClass = null;
		this._self.onselectstart = null;
		this.deleteAllItems();
		if(this._tableIndex){
			this._tableIndex.removeEventListener("dataChange", this);
			this._tableIndex = null;
		}
		this._filter = null;
		try{
			if(this._model){
				this._model.removeEventListener("dataChange", this);
				this._model = null;
			}
		}catch(ex){
			//[TODO]未释放的脚本对象错误
		}
		_super.dispose.apply(this);
	};
	this.getActiveItem = function(){
		return this._activeItem;
	};
	this.setActiveItem = function(v){
		this._activeItem = v;
	};
	this.activeItem = function(v){
		if(this._activeItem == v) return;
		if(this._activeItem){
			this._activeItem.deactivate();
		}
		if(v){
			v.activate();
			this._activeItem = v;
			this.fireEvent({"type": "itemChange", "sender": v._self, "item": v});
		}else{
			this._activeItem = v;
		}
	};
	/**
	 * 设置视图组件的数据模型
	 * @param {MetaTable} v 数据表(模型层)
	 * @param {Function|String} filter 过滤器或者索引的名字
	 */
	this.setModel = function(v, filter){
		this._model = v;
		switch(typeof filter){
		case "function":
			this.setFilter(filter);
			//v.addEventListener("dataChange", this);
			this.addListener(v, "dataChange", this, "onDataChange");
			break;
		case "string":
			var index = v.getIndex2(filter);
			this._tableIndex = index;
			//index.addEventListener("dataChange", this);
			this.addListener(index, "dataChange", this, "onDataChange");
			//if(v._className == "CityTable"){
				runtime.startTimer(0, index, "dispatchExistRecords");  //滞后加载已有的数据，因为相关组件的_self属性可能还不存在
			//}
			break;
		default:
			//v.addEventListener("dataChange", this);
			this.addListener(v, "dataChange", this, "onDataChange");
			break;
		}
	};
	this.getFilter = function(){
		return this._filter;
	};
	this.setFilter = function(v){
		this._filter = v;
	};
	this.getTableIndex = function(){
		return this._tableIndex;
	};
	this.getDataList = function(){
		if(this._filter){
			return this._model.getListByFilter(this._filter);
		}else{
			return this._model.getList();
		}
	};
	this.setItemClass = function(v){
		this._itemClass = v;
	};
	this.exist = function(key){
		return key in this._hash;
	};
	this.getItem = function(id){
		return this._hash[id];
	};
	this.pushItem1 = function(k, item){
		this._hash[k] = item;
		this._list.push(item);
	};
	this.pushItem = function(item, pos){
		if(item._data){
			var k = item._data[this._model.getPrimaryKey()];
			if(!(k in this._hash)){
				this._hash[k] = item;
				if(typeof pos != "undefined" && pos < this._list.length){
					this._list.splice(pos, 0, item);
				}else{
					this._list.push(item);
				}
			}
		}else{
			if(typeof pos != "undefined" && pos < this._list.length){
				this._list.splice(pos, 0, item);
			}else{
				this._list.push(item);
			}
		}
	};
	/* *
	 * @param {String} act
	 * @param {JsonObject} data
	 * @param {JsonObject} olddata
	 */
	/*
	this.dispatchDataChange = function(act, data, olddata){
		this.onDataChange.apply(this, arguments);
	};
	*/
	/**
	 * 数据变更响应事件，主要用来分派数据变化
	 * @param {DataChangeEvent} ev 数据变更事件
	 */
	this.onDataChange = function(ev){
		var act = ev.act;
		var data = ev.data;
		//var olddata = ev.olddata;
		var a = act.split("_")[1];
		switch(a){
		case "adds":  //批量添加
			this.insertItems(data, ev.pos);
			break;
		case "add":
			if(!this._filter || this._filter(data)){  //有过滤器的话，需要先通过过滤器，才添加
				var id = data[this._model.getPrimaryKey()];
				if(!(id in this._hash)){
					this.insertItem(data, ev.pos);
				}
			}
			break;
		case "mod": 
			//if(!this._filter || this._filter(data)){  //有过滤器的话，情况比较复杂，先交给“视图组件”来自行处理
				//this.onDataChange.apply(this, arguments);
				var id = data[this._model.getPrimaryKey()];
				if(id in this._hash){
					this.updateItem(data);
				}
			//}
			break;
		case "del":
		case "remove":
			if(!this._filter || this._filter(data)){  //有过滤器的话，需要先通过过滤器，才删除
				//this.onDataChange.apply(this, arguments);
				this.deleteItem(data);
			}
			break;
		/*
		case "update":
		case "delete":
		case "clear":
		case "up":
		case "adds":
		case "clean":
		*/
		default:
			//_super.onDataChange.apply(this, arguments);
			break;
		}
	};
	this._insertItem = function(data, pos){
		var item = new this._itemClass();
		var len = this._list.length;
		if(pos < len){
			item.__insert = this._list[pos]._self;
		}
		item.create(this, data, this._itemTpl);
		this.pushItem(item, pos);
		if(pos < len){
			delete item.__insert;
		}
	};
	this.insertItem = function(data, pos){
		this._insertItem(data, pos);
	};
	this.insertItems = function(data, pos){
		for(var i = 0, len = data.length; i < len; i++){
			this._insertItem(data[i], pos + i);
		}
	};
	this.updateItem = function(data){
	};
	this._deleteItem = function(data){
		var id = data[this._model.getPrimaryKey()];
		if(id in this._hash){
			var item = this._hash[id];
			if(item == this._activeItem){
				this._activeItem = null;
			}
			item._self.parentNode.removeChild(item._self);
			var n = this._list.indexOf(item);
			if(n != -1){
				this._list[n] = null;
				this._list.removeAt(n);
			}
			delete this._hash[id];
			item.dispose();
			item = null;
		}
	};
	this.deleteItem = function(data){
		this._deleteItem(data);
	};
	this.deleteAllItems = function(){
		this._activeItem = null;
		for(var i = 0, len = this._list.length; i < len; i++){
			if(!this._list[i]._disposed){
				this._list[i].dispose();
			}
			this._list[i] = null;
		}
		this._list = [];
		for(var k in this._hash){
			//this._hash[k].dispose();
			delete this._hash[k];
		}
	};
});